package com.hinnotek.warehouse.viewmodel

import android.app.Application
import android.net.ParseException
import androidx.lifecycle.*
import com.google.gson.JsonParseException
import com.hinnotek.warehouse.api.WarehouseApi
import com.lee.common.network.CONNECT_EXCEPTION_CODE
import com.lee.common.network.HTTP_EXCEPTION_CODE
import com.lee.common.network.WarehouseResponse
import com.lee.common.support.SingleLiveData
import com.lee.common.utils.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.json.JSONException
import retrofit2.HttpException
import timber.log.Timber
import java.io.InterruptedIOException
import java.net.ConnectException

private const val TAG = "BaseViewModel"

open class BaseViewModel : AndroidViewModel(Application()) {

    protected val api = WarehouseApi.get()

    val refreshTrigger = MutableLiveData<Boolean>()
    val loading = MutableLiveData<Boolean>()
    protected val page = MutableLiveData<Int>()
    val refreshing = MutableLiveData<Boolean>()
    val moreLoading = MutableLiveData<Boolean>()
    val hasMore = MutableLiveData<Boolean>()
    val autoRefresh = MutableLiveData<Boolean>()//SmartRefreshLayout自动刷新标记
    val dialogMsg = MutableLiveData<String>()
    val isEmpty = MutableLiveData<Int>()// 1-空 2-错误

    var keyInt = 0
    var keyString = ""
    var isSuccess = false

    val pageSize = PAGE_SIZE
    var isFirst = true  //是否第一次加载

    open fun loadMore() {
        Timber.e("LiveData loadMore()")
        isFirst = false
        page.value = (page.value ?: 0) + 1
        moreLoading.value = true
    }


    /**
     * 自动刷新
     */
    fun autoRefresh() {
        Timber.e("LiveData autoRefresh()")
        autoRefresh.value = true
    }

    open fun refresh() {
        Timber.e("LiveData refresh()")
        refreshing.value = true
        isFirst = true
        page.value = 1
    }

    /**
     * 处理分页数据
     */
    fun <T> mapPage(source: LiveData<WarehouseResponse<MutableList<T>>>): LiveData<MutableList<T>> {
        return Transformations.map(source) {
            refreshing.value = false
            moreLoading.value = false
            loading.value = false
            if (it == null) {
                isSuccess = false
                mutableListOf()
            } else {
                isSuccess = it.code == 200
                val isHasValue: Boolean

                if (it.data == null) isHasValue = false
                else isHasValue = it.data!!.size >= PAGE_SIZE

                hasMore.value = isHasValue

                executeResp(it.code, it.msg, !isHasValue)
                it.data ?: mutableListOf()
            }

        }
    }

    fun <T> mapData(source: LiveData<WarehouseResponse<T>>): LiveData<T> {
        return Transformations.map(source) {
            loading.value = false
            if (it == null) {
                isSuccess = false
                return@map null
            }
            isSuccess = it.code == 200
            executeResp(it.code, it.msg, false)
            return@map it.data
        }
    }

    val showCode = arrayListOf(
        LOGIN_TOKEN_OUT,
        MODEL_MISMATCH,
        DEVICE_WAREHOUSED,
        DEVICE_EX_WAREHOUSE,
        DEVICE_BORROW,
        DEVICE_DAMAGE,
        DEVICE_NOT,
        DEVICE_NOT_FIND,
        ERROR_CODE_N,
        NOT_FIND_WAREHOUSE,
        DEVICE_SCAN_COMPLETE,
        APPLY_FROM_NO_COMPLETE,
        STOCK_NOT_ENOUGH,
        STATE_ERROR,
        Old_Pass_Error
    )

    fun executeResp(code: Int?, msg: String, empty: Boolean) {
        var msgS = msg
        try {
            when (code) {
                200 -> {
                    if (empty) isEmpty.value = 1
                }
                LOGIN_TOKEN_OUT -> {
                    msgS = "您的登录信息已过期！"
                    SharedPreUtils.setBoolean("isToLogin", true)
                    isEmpty.value = 2
                }
                LOGIN_NOT_EXIST -> {
                    msgS = "用户不存在！"
                    isEmpty.value = 2
                }
                Old_Pass_Error -> {
                    msgS = "密码错误！"
                }
                else -> {
                    isEmpty.value = 2
                }

            }
        } catch (e: Exception) {
            e.printStackTrace()
            //非后台返回错误，捕获到的异常
            val error: Throwable = e
            if (error is HttpException) { //网络错误
                msgS = "网络异常，请稍候再试..."
            } else if (error is ConnectException) {
                //无网络连接
                msgS = "无网络连接，请打开网络..."
            } else if (error is InterruptedIOException) {
                //连接超时
                msgS = "网络异常，请稍候再试..."
            } else if (error is JsonParseException
                || error is JSONException
                || error is ParseException
            ) {
                //解析错误
                msgS = "数据错误，请稍候再试..."
            } else {
                //未知错误
                msgS = "未知错误，请稍候再试..."
            }


        } finally {
            Timber.e("msg==" + msgS)
            for (i in showCode) {
                if (code == i) {
                    dialogMsg.postValue(msgS)
                    return
                }
            }

            if (code == CONNECT_EXCEPTION_CODE || code == HTTP_EXCEPTION_CODE) {
                ToastUtils.showShort("网络异常，请稍候再试!")
            }
        }
    }


    open fun loadData() {
        refreshTrigger.value = true
        loading.value = true
    }

    fun attachLoading(otherState: MutableLiveData<Boolean>) {
        loading.observeForever {
            otherState.value = it
        }
    }


}